package com.wutong.erb.service;

import com.wutong.erb.dto.UserDTO;
import com.wutong.erb.entity.user.User;
import com.wutong.erb.exception.*;
import com.wutong.erb.mapper.UserMapper;
import com.wutong.erb.other.Response;
import com.wutong.erb.util.JwtUtil;
import com.wutong.erb.util.SecretUtil;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户服务
 *
 * @author wutong
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {

    private final UserMapper userMapper;

    protected final User getUserByToken(String accessToken) {
        return JwtUtil.getTokenClaims(accessToken, new JwtUtil.TokenClaimsExceptionHandlerByDefault<>() {
            @Override
            public User normalHandler(Claims claims) {
                return userMapper.selectByUsername(claims.getSubject());
            }

            @Override
            public User defaultHandler() {
                return null;
            }

            @Override
            public User handleOtherException(Exception e) {
                return null;
            }
        });
    }

    @Transactional
    public UserDTO.UserInfoDTO getUserInfo(String accessToken) {
        User user = getUserByToken(accessToken);
        UserDTO.UserInfoDTO userInfoDTO = new UserDTO.UserInfoDTO();
        if (user == null) {
            return null;
        }
        BeanUtils.copyProperties(user, userInfoDTO);
        log.debug("getUserInfo: {}", userInfoDTO);
        return userInfoDTO;
    }

    @Transactional
    public UserDTO.UserInfoDTO updateUserInfo(UserDTO.UserUpdateInfoDTO userInfoDTO, String accessToken) {
        log.debug("updateUserInfo: {}", userInfoDTO);
        User user = getUserByToken(accessToken);
        if (user == null) {
            return null;
        }
        BeanUtils.copyProperties(userInfoDTO, user);
        if (userMapper.updateUser(user) > 0) {
            return getUserInfo(accessToken);
        } else {
            return null;
        }
    }

    @Transactional
    public Response updaterPassword(UserDTO.UserUpdatePwdDTO updatePwdDTO, String accessToken) {
        log.debug("updatePassword: {}", updatePwdDTO);
        // 从验证中获取用户信息
        User user = getUserByToken(accessToken);
        if (user == null) {
            throw new UserNotFoundException(null);
        }
        // 验证旧密码是否正确
        if (!SecretUtil.check(updatePwdDTO.getOldPassword(), user.getPasswordHash())) {
            throw new PasswordNotMatchException();
        }
        // 更新密码
        user.setPasswordHash(SecretUtil.encrypt(updatePwdDTO.getNewPassword()));
        log.debug("updatePassword: {}", user);
        if (userMapper.updatePassword(user) > 0) {
            return Response.success()
                    .message("密码修改成功")
                    .build();
        } else {
            return Response.failure()
                    .message("密码修改失败")
                    .build();
        }
    }
}
